package rest

import (
	"path"
	"strconv"
	"../dog"
	"net/http"
	"strings"
)

type DogModel struct {
	url_model

	Name        string
	Id          int
	HungerCycle int64
	LifeCycle   int64
}

type DogController struct {
	dogkeeper *dog.DogKeeper
}

func (this *DogController) GetSourceName() string {
	return "/API/Dogs/"
}

func (this *DogController) IsRoot() bool {
	return false
}

func (this *DogController) Get(r interface{}) interface{} {
	obj := this.findDog(r)
	dog, success := obj.(dog.IDog)

	if success {
		return DogModel{
			url_model: url_model{
				Url: GetDogItemUrl(dog.GetDogId()),
			},
			Name:        dog.GetDogName(),
			Id:          dog.GetDogId(),
			HungerCycle: dog.GetHungerCycle(),
			LifeCycle:   dog.GetLifeCycle(),
		}
	} else {
		return obj
	}

}

func (this *DogController) Put(r interface{}) interface{} {
	obj := this.findDog(r)
	dog, success := obj.(dog.IDog)

	if success {
		dog.Feed()

		return DogModel{
			url_model: url_model{
				Url: GetDogItemUrl(dog.GetDogId()),
			},
			Name:        dog.GetDogName(),
			Id:          dog.GetDogId(),
			HungerCycle: dog.GetHungerCycle(),
			LifeCycle:   dog.GetLifeCycle(),
		}
	} else {
		return obj
	}
}

func (this *DogController) Post(r interface{}) interface{} {
	obj := this.findDog(r)
	dog, success := obj.(dog.IDog)

	if success {
		request, _ := r.(*http.Request)

		request.ParseForm()
		hc := request.FormValue("HungerCycle")
		if hc != "" {
			//hci, err := strconv.Atoi(hc)
			hci, err := strconv.ParseInt(hc, 10, 64)
			if err != nil {
				dog.SetHungerCycle(hci)
			}
		}

		name := request.FormValue("Name")
		if name != "" {
			dog.SetDogName(name)
		}

		return DogModel{
			url_model: url_model{
				Url: GetDogItemUrl(dog.GetDogId()),
			},
			Name:        dog.GetDogName(),
			Id:          dog.GetDogId(),
			HungerCycle: dog.GetHungerCycle(),
			LifeCycle:   dog.GetLifeCycle(),
		}
	} else {
		return obj
	}
}

func (this *DogController) findDog(r interface{}) interface{} {
	request, success := r.(*http.Request)
	if !success {
		return Error(request, "request must be *http.Request")
	}

	if !strings.Contains(request.RequestURI, this.GetSourceName()) {
		return Error(request, "Url must be start with "+this.GetSourceName())
	}

	id_str := request.RequestURI[len(this.GetSourceName()):]
	id, err := strconv.Atoi(id_str)
	if err != nil {
		return Error(request, "convert error "+id_str)
	}
	dog := this.dogkeeper.FindDog(id)
	if dog == nil {
		return Error(request, "not found dog")
	}

	return dog
}

func GetDogItemUrl(id int) string {
	return path.Join("/API/Dogs/", strconv.Itoa(id))
}
